package pl.matt.service.impl;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.media.jai.PlanarImage;

import pl.matt.dao.FrameDao;
import pl.matt.dao.FrameRegionDao;
import pl.matt.dao.VideoDao;
import pl.matt.media.extractor.FramesExtractor;
import pl.matt.media.extractor.impl.MplayerFramesExtractor;
import pl.matt.media.utils.ImageUtils;
import pl.matt.model.Frame;
import pl.matt.model.Video;
import pl.matt.service.VideoService;

public class VideoServiceImpl implements VideoService {

	private FrameDao frameDao;
	private VideoDao videoDao;
	private FrameRegionDao frameRegionDao;
	private FramesExtractor framesExtractor = new MplayerFramesExtractor();
	private String filesRepositoryPath;
	private String frameExtention = ".jpg";
	
	@Override
	public void extractFrames(String videoName, String videoFilePath) {
		try {
			String outDir = filesRepositoryPath + File.separator + videoName;
			framesExtractor.extractFrames(videoFilePath, outDir);
			File dir = new File(outDir);
			File[] files = dir.listFiles(new FilenameFilter() {
				
				@Override
				public boolean accept(File dir, String name) {
					return name.endsWith(frameExtention);
				}
			});
			List<File> filesList = Arrays.asList(files);
			Collections.sort(filesList);
			saveVideo(videoName, videoFilePath, filesList);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	private void saveVideo(String videoName, String videoFilePath, List<File> filesList) {
		Video video = videoDao.readByName(videoName);
		if (video == null) {
			video = new Video();
			video.setName(videoName);
		} else {
			frameRegionDao.deleteByVideo(video);
			frameDao.deleteByVideo(video);
		}
		video.setVideoFilePath((new File(videoFilePath)).getAbsolutePath());
		videoDao.createOrUpdate(video);
		int number = 0;
		for (File file : filesList) {
			Frame frame = new Frame();
			frame.setVideo(video);
			String path = file.getAbsolutePath();
			frame.setFilePath(path);
			frame.setNumber(number);
			PlanarImage image = ImageUtils.readImage(path);
			frame.setWidth(image.getWidth());
			frame.setHeight(image.getHeight());			
			number++;
			frameDao.create(frame);
		}
	}

	public void setFrameDao(FrameDao frameDao) {
		this.frameDao = frameDao;
	}

	public void setFramesExtractor(FramesExtractor framesExtractor) {
		this.framesExtractor = framesExtractor;
	}

	public void setFilesRepositoryPath(String outputDirectoryPath) {
		this.filesRepositoryPath = outputDirectoryPath;
	}

	public void setFrameExtention(String frameExtention) {
		this.frameExtention = frameExtention;
	}

	public void setVideoDao(VideoDao videoDao) {
		this.videoDao = videoDao;
	}

	public void setFrameRegionDao(FrameRegionDao frameRegionDao) {
		this.frameRegionDao = frameRegionDao;
	}

}
